﻿using System.Management;

namespace WinQuickIP
{
    /// <summary>
    /// Wrapper around a ManagementObject for Win32_NetworkAdapterConfiguration WMI calls
    /// </summary>
    public class Win32_NetworkAdapterConfiguration
    {
        /// <summary>
        /// Get a friendly response message from a response code
        /// </summary>
        /// <param name="code">Response code</param>
        /// <returns>Friendly message</returns>
        public static string GetResponseMessage(uint code)
        {
            switch (code)
            {
                case 0:
                    return "Successful completion, no reboot required.";
                case 1:
                    return "Successful completion, reboot required.";
                case 64:
                    return "Method not supported when the NIC is in DHCP mode.  ";
                case 65:
                    return "Unknown failure.";
                case 66:
                    return "Invalid subnet mask.  ";
                case 67:
                    return "An error occurred while processing an instance that was returned.";
                case 68:
                    return "Invalid input parameter.";
                case 69:
                    return "More than five gateways specified.";
                case 70:
                    return "Invalid IP address.";
                case 71:
                    return "Invalid gateway IP address.  ";
                case 72:
                    return "An error occurred while accessing the registry for the requested information.  ";
                case 73:
                    return "Invalid domain name.  ";
                case 74:
                    return "Invalid host name.  ";
                case 75:
                    return "No primary or secondary WINS server defined.  ";
                case 76:
                    return "Invalid file.";
                case 77:
                    return "Invalid system path.";
                case 78:
                    return "File copy failed.  ";
                case 79:
                    return "Invalid security parameter.  ";
                case 80:
                    return "Unable to configure TCP/IP service.  ";
                case 81:
                    return "Unable to configure DHCP service.";
                case 82:
                    return "Unable to renew DHCP lease.";
                case 83:
                    return "Unable to release DHCP lease.";
                case 84:
                    return "IP not enabled on adapter.";
                case 85:
                    return "IPX not enabled on adapter.";
                case 86:
                    return "Frame or network number bounds error.";
                case 87:
                    return "Invalid frame type.";
                case 88:
                    return "Invalid network number.";
                case 89:
                    return "Duplicate network number.";
                case 90:
                    return "Parameter out of bounds.";
                case 91:
                    return "Access denied.";
                case 92:
                    return "Out of memory.";
                case 93:
                    return "Already exists.";
                case 94:
                    return "Path, file, or object not found.";
                case 95:
                    return "Unable to notify service.";
                case 96:
                    return "Unable to notify DNS service.";
                case 97:
                    return "Interface not configurable.";
                case 98:
                    return "Not all DHCP leases can be released or renewed.";
                case 100:
                    return "DHCP not enabled on adapter.";
            }
            return "Unknown code";
        }

        private readonly ManagementObject managementObject;

        /// <summary>
        /// Creates a new instance of the Win32_NetworkAdapterConfiguration class
        /// </summary>
        /// <param name="managementObject">Win32_NetworkAdapterConfiguration ManagementObject to wrap calls around</param>
        public Win32_NetworkAdapterConfiguration(ManagementObject managementObject)
        {
            this.managementObject = managementObject;
        }

        #region Properties
        /// <summary>
        /// Gets the base ManagementObject
        /// </summary>
        public ManagementObject ManagementObject
        {
            get { return managementObject; }
        }
        /// <summary>
        /// Array of IP addresses of default gateways that the computer system uses.
        /// </summary>
        /// <example>
        /// Example: "192.168.12.1 192.168.46.1"
        /// </example>
        public string[] DefaultIPGateway
        {
            get { return (string[])managementObject["DefaultIPGateway"]; }
        }

        /// <summary>
        /// Description of the CIM_Setting object. This property is inherited from CIM_Setting.
        /// </summary>
        public string Description
        {
            get { return (string)managementObject["Description"]; }
        }
        /// <summary>
        /// If TRUE, the dynamic host configuration protocol (DHCP) server automatically assigns an
        ///  IP address to the computer system when establishing a network connection.
        /// </summary>
        public bool DHCPEnabled
        {
            get { return (bool)managementObject["DHCPEnabled"]; }
        }

        /// <summary>
        /// Array of server IP addresses to be used in querying for DNS servers.
        /// </summary>
        public string[] DNSServerSearchOrder
        {
            get { return (string[])managementObject["DNSServerSearchOrder"]; }
        }

        /// <summary>
        /// Index number of the Windows network adapter configuration. The index number is used when there is more 
        /// than one configuration available.
        /// </summary>
        public uint Index
        {
            get { return (uint)managementObject["Index"]; }
        }

        /// <summary>
        /// If TRUE, TCP/IP is bound and enabled on this network adapter.
        /// </summary>
        public bool IPEnabled
        {
            get { return (bool)managementObject["IPEnabled"]; }
        }

        /// <summary>
        /// Array of all of the IP addresses associated with the current network adapter. Starting with Windows
        ///  Vista, this property can contain either IPv6 addresses or IPv4 addresses. For more information, see IPv6 and IPv4 Support in WMI.
        /// </summary>
        public string[] IPAddress
        {
            get { return (string[])managementObject["IPAddress"]; }
        }

        /// <summary>
        /// Array of all of the subnet masks associated with the current network adapter.
        /// </summary>
        public string[] IPSubnet
        {
            get { return (string[])managementObject["IPSubnet"]; }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Enables the Dynamic Host Configuration Protocol (DHCP) for service with this network adapter.
        /// </summary>
        /// <returns>
        /// Returns a value of 0 (zero) for a successful completion when a reboot is not required,
        /// 1 (one) for a successful completion when a reboot is required, 
        /// and any other number if there is an error.
        /// </returns>
        public uint EnableDHCP()
        {
            return (uint)managementObject.InvokeMethod("EnableDHCP", new object[] { });
        }

        /// <summary>
        /// Enables static TCP/IP addressing for the target network adapter.
        /// </summary>
        /// <returns>
        /// Returns a value of 0 (zero) for a successful completion when a reboot is not required, 
        /// 1 (one) for a successful completion when a reboot is required, 
        /// and any other number if there is an error.
        /// </returns>
        public uint EnableStatic(string[] ipAddresses, string[] subnetMasks)
        {
            //var newIp = managementObject.GetMethodParameters("EnableStatic");

            //newIp["IPAddress"] = ipAddresses;
            //newIp["SubnetMask"] = subnetMasks;

            return (uint)managementObject.InvokeMethod("EnableStatic", new object[] { ipAddresses, subnetMasks });
            //return (uint)managementObject.InvokeMethod("EnableStatic", newIp, null);
        }

        /// <summary>
        /// Releases the IP address bound to a specific DHCP-enabled network adapter.
        /// </summary>
        /// <returns>
        /// Returns a value of 0 (zero) for a successful completion when no reboot is required, 
        /// 1 (one) for a successful completion when a reboot is required, 
        /// and a different number if there is an error. 
        /// </returns>
        public uint ReleaseDHCPLease()
        {
            return (uint)managementObject.InvokeMethod("ReleaseDHCPLease", new object[] { });
        }

        /// <summary>
        /// Renews the IP address on specific DHCP-enabled network adapters.
        /// </summary>
        /// <returns>
        ///  Returns a value of 0 (zero) for a successful completion when no reboot is required, 
        /// 1 (one) for a successful completion when a reboot is required, 
        /// and a different number if there is an error. 
        /// </returns>
        public uint RenewDHCPLease()
        {
            return (uint)managementObject.InvokeMethod("RenewDHCPLease", new object[] { });
        }

        /// <summary>
        /// Sets the server search order as an array of elements.
        /// </summary>
        /// <param name="dnsServerSearchOrder">
        /// List of server IP addresses to query for DNS servers. 
        /// </param>
        /// <returns>
        /// Returns a value of 0 (zero) for a successful completion when a reboot is not required, 
        /// 1 (one) for a successful completion when a reboot is required, 
        /// and any other value if there is an error.</returns>
        public uint SetDNSServerSearchOrder(string[] dnsServerSearchOrder)
        {
            return (uint)managementObject.InvokeMethod("SetDNSServerSearchOrder", new object[] { dnsServerSearchOrder });

        }

        /// <summary>
        /// Specifies a list of gateways for routing packets destined for a different subnet than the one this adapter is connected to.
        /// </summary>
        /// <param name="defaultIPGateway">List of IP addresses to gateways where network packets are routed.</param>
        /// <param name="gatewayCostMetric">
        /// Assigns a value that ranges from 1 to 9999, which is used to calculate the fastest and most reliable routes. 
        /// The values of this parameter correspond with the values in the DefaultIPGateway parameter. 
        /// The default value for a gateway is 1. This optional parameter is new for Windows 2000. 
        /// </param>
        /// <returns>
        /// Returns a value of 0 (zero) for a successful completion when a reboot is not required, 
        /// 1 (one) for a successful completion when a reboot is required, 
        /// and any other value if there is an error.
        /// </returns>
        public uint SetGateways(string[] defaultIPGateway, uint[] gatewayCostMetric)
        {
            return (uint)managementObject.InvokeMethod("SetGateways", new object[] { defaultIPGateway, gatewayCostMetric });
        }

        #endregion
    }
}
